// store/register/ActionManager.hpp

#ifndef ACTIONMANAGER_HPP
#define ACTIONMANAGER_HPP


#include "store/type/MetaMoldType.hpp"
#include "store/type/ActionWrapper.hpp"
#include "store/struct/Synthetic.hpp"
#include "store/struct/Basic.hpp"
#include "store/Huben.hpp"
#include "tool/Tool.hpp"
#include <functional>
#include <QDebug>
#include <QTimer>

/**
 * @brief 动作管理类 ActionManager，负责注册所有的动作和变更处理函数
 */
class ActionManager {
public:
    /**
     * @brief 构造函数，注册动作和变更
     */
    ActionManager() {
        registerActions();
        registerMutations();
    }

private:
    /**
     * @brief 注册所有的动作处理函数
     */
    void registerActions() {

        // 注册加载InitBasic动作
        Huben::instance().registerAction(ActionWrapper::ActionType::InitBasic, [this](const QVariant &payload) {
            Basic basic = Huben::instance().search<Basic>(ActionWrapper::StateKey::Basic);
            Huben::instance().commit(ActionWrapper::ActionType::SetBasic, QVariant::fromValue(basic));
        });

        Huben::instance().registerAction(ActionWrapper::ActionType::InitModify, [this](const QVariant &payload) {
            Basic basic = Huben::instance().search<Basic>(ActionWrapper::StateKey::Basic);
            QList<DurationCarrier> durations = Tool::queryRhythmToDurationCarrier(basic.rhythms); // 获取 durations 列表
            QList<LadderLineCarrier> ladderLines = Tool::queryLadderLineToLadderLineCarrier(basic.ladderLines);
            Synthetic synthetic(basic.startTime, basic.endTime, durations, ladderLines);
            Huben::instance().commit(ActionWrapper::ActionType::SetSynthetic, QVariant::fromValue(synthetic));
        });

        Huben::instance().registerAction(ActionWrapper::ActionType::EditModify, [this](const QVariant &payload) {
            QMap<QString, QVariant> palyload = payload.toMap();
            Basic basic = Huben::instance().search<Basic>(ActionWrapper::StateKey::Basic);
            editBasicToModify(basic, payload);
            Synthetic synthetic = moldTypeSwitch(palyload["TypeChart"].toInt(), basic);
            Huben::instance().commit(ActionWrapper::ActionType::SetBasic, QVariant::fromValue(basic));
            Huben::instance().commit(ActionWrapper::ActionType::SetSynthetic, QVariant::fromValue(synthetic));

        });


    }

    /**
     * @brief 注册所有的变更处理函数
     */
    void registerMutations() {
        Huben::instance().registerMutation(ActionWrapper::ActionType::SetBasic, ActionWrapper::StateKey::Basic,
        [this](const QVariant &payload) {
            Huben::instance().updateState(ActionWrapper::StateKey::Basic, payload);
        });

        Huben::instance().registerMutation(ActionWrapper::ActionType::SetSynthetic, ActionWrapper::StateKey::Synthetic,
        [this](const QVariant &payload) {
            Huben::instance().updateState(ActionWrapper::StateKey::Synthetic, payload);
        });

    }

    static Synthetic  moldTypeSwitch(int moldType, Basic basic) {
        Synthetic synthetic;
        switch (moldType) {
        case 1: {
            QList<LadderLineCarrier> ladderLines = Tool::queryLadderLineToLadderLineCarrier(basic.ladderLines, basic.startTime, basic.endTime);
            synthetic = Synthetic(basic.startTime, basic.endTime, ladderLines);
            break;
        }
        case 0: {
            QList<DurationCarrier> durations = Tool::queryRhythmToDurationCarrier(basic.rhythms, basic.startTime, basic.endTime);
            synthetic = Synthetic(basic.startTime, basic.endTime, durations);
            break;
        }
        default:
            qDebug() << "EditModify";
            break;
        }
        return synthetic;
    }



    /**
     * @brief 从给定的 QVariant 更新 Basic 对象的属性
     *
     * 该函数根据传入的 QVariant 对象（payload）中的数据，自动更新 Basic 对象的 `startTime`、`endTime` 和 `initialize` 数据。
     * - 如果 payload 包含 "StartTime"，则更新 Basic 对象的 `startTime`。
     * - 如果 payload 包含 "EndTime"，则更新 Basic 对象的 `endTime`。
     * - 如果 payload 包含 "SelectDate"，则根据该日期更新 Basic 对象的 `initialize` 数据。
     *
     * @param basic 要更新的 Basic 对象
     * @param payload 存储了更新数据的 QVariant 对象，其中包含键值对（"StartTime"、"EndTime"、"SelectDate"）
     */
    static void editBasicToModify(Basic &basic, const QVariant &payload) {
        // 将 QVariant 转换为 QMap<QString, QVariant>
        QMap<QString, QVariant> data = payload.toMap();

        // 创建键与更新逻辑的映射
        QMap<QString, std::function<void()>> updateActions;

        updateActions["StartTime"] = [&]() {
            basic.startTime = toQTimeToQDateTime(QTime::fromString(data["StartTime"].toString(), "HH:mm:ss"));
        };

        updateActions["EndTime"] = [&]() {
            basic.endTime = toQTimeToQDateTime(QTime::fromString(data["EndTime"].toString(), "HH:mm:ss"));
        };

        updateActions["SelectDate"] = [&]() {
            QString selectDate = data["SelectDate"].toString();
            basic = Tool::ImportXML("", selectDate);
        };

        // 遍历 payload，自动调用对应的更新逻辑
        for (auto it = data.begin(); it != data.end(); ++it) {
            QString key = it.key();
            if (updateActions.contains(key)) {
                updateActions[key]();
            }
        }
    }


    static QDateTime toQTimeToQDateTime(const QTime &time) {
        QDate currentDate = QDate::currentDate();
        QDateTime resultDateTime(currentDate, QTime(0, 0, 0, 0));

        return QDateTime(currentDate, time);
    }

};

#endif // ACTIONMANAGER_HPP
